﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;
using System.Threading;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using System.Windows.Forms;

namespace Akiha.Core
{
    public static class MapWrapper
    {
        private static ISimpleFillSymbol fillSymbol = null;
        private static ISimpleLineSymbol lineSymbol = null;
        private static ISimpleMarkerSymbol markerSymbol = null;

        public static void FlashGeometries(IActiveView activeView, IGeometry[] geometries)
        {
            IScreenDisplay screenDisplay = activeView.ScreenDisplay;
            IRgbColor pRGBColor = new RgbColorClass
            {
                Red = 255,
                Green = 255,
                Blue = 0
            };
            screenDisplay.StartDrawing(screenDisplay.hDC, -1);
            foreach (IGeometry geometry in geometries)
            {
                switch (geometry.GeometryType)
                {
                    case esriGeometryType.esriGeometryPoint:
                        if (markerSymbol == null)
                        {
                            markerSymbol = new SimpleMarkerSymbolClass();
                            markerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                            markerSymbol.Color = RgbColorWrapper.GetRGBColor(255, 255, 0,255);
                        }
                        screenDisplay.SetSymbol(markerSymbol as ISymbol);
                        screenDisplay.DrawPoint(geometry);
                        break;

                    case esriGeometryType.esriGeometryPolyline:
                    case esriGeometryType.esriGeometryLine:
                        if (lineSymbol == null)
                        {
                            lineSymbol = new SimpleLineSymbolClass();
                            lineSymbol.Width = 2.0;
                            lineSymbol.Color = RgbColorWrapper.GetRGBColor(255, 0, 0,255);
                        }
                        screenDisplay.SetSymbol(lineSymbol as ISymbol);
                        screenDisplay.DrawPolyline(geometry);
                        break;

                    case esriGeometryType.esriGeometryPolygon:
                        if (fillSymbol == null)
                        {
                            fillSymbol = new SimpleFillSymbolClass();
                            fillSymbol.Outline = lineSymbol;
                            fillSymbol.Color = RgbColorWrapper.GetRGBColor(0, 0, 255,255); ;
                        }
                        screenDisplay.SetSymbol(fillSymbol as ISymbol);
                        screenDisplay.DrawPolygon(geometry);
                        break;
                }
            }
            screenDisplay.FinishDrawing();
            Thread.Sleep(500);
            activeView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
        }

        public static void FlashDefaultGeometry(IMapControlDefault mapComtrol, IGeometry geometry)
        {
            ISymbol symbol = null;
            IRgbColor rgbColor = null;
            switch (geometry.GeometryType)
            {
                case esriGeometryType.esriGeometryPoint:
                    rgbColor = RgbColorWrapper.GetRGBColor(255, 255, 0,255);
                    break;

                case esriGeometryType.esriGeometryPolyline:
                case esriGeometryType.esriGeometryLine:
                    rgbColor = RgbColorWrapper.GetRGBColor(255, 0, 0,255);
                    break;

                case esriGeometryType.esriGeometryPolygon:
                    rgbColor = RgbColorWrapper.GetRGBColor(0, 0, 255,255); ;
                    break;
            }
            symbol = SymbolWrapper.GetSpecifyColorSymbol(geometry.GeometryType, rgbColor as IColor);
            mapComtrol.FlashShape(geometry, 3, 300, symbol);
        }

        public static void SetClipGeometry(IMap map, IGeometry clipGeometry)
        {
            IMapClipOptions options = map as IMapClipOptions; ;
            options.ClipType = esriMapClipType.esriMapClipShape;
            map.ClipGeometry = clipGeometry;
            map.ClipBorder = new SymbolBorderClass();
        }

        public static double GetMapDistance(IActiveView activeView, int pixelsPoints)
        {
            if (activeView == null)
            {
                throw new ArgumentNullException("activeView");
            }
            if (activeView.FocusMap.MapUnits == esriUnits.esriUnknownUnits)
            {
                throw new Exception("未知地图单位，无法将屏幕点距离换算成地图距离。请先设置地图单位!");
            }
            return activeView.ScreenDisplay.DisplayTransformation.FromPoints((double)pixelsPoints);
        }

        public static bool MapExport(IMap map, string outputFile, double resolution)
        {
            bool IsExport;
            IActiveView activeView = map as IActiveView;
            if (activeView == null)
            {
                return false;
            }
            IExport exporter = null;
            switch (System.IO.Path.GetExtension(outputFile).ToLower())
            {
                case ".jpg":
                    exporter = new ExportJPEGClass();
                    break;

                case ".pdf":
                    exporter = new ExportPDFClass();
                    break;

                case ".png":
                    exporter = new ExportPNGClass();
                    break;

                case ".tif":
                    exporter = new ExportTIFFClass();
                    break;

                case ".bmp":
                    exporter = new ExportBMPClass();
                    break;

                case ".gif":
                    exporter = new ExportGIFClass();
                    break;

                default:
                    throw new Exception("输出图片格式不支持！");
            }
            try
            {
                exporter.ExportFileName = outputFile;
                exporter.Resolution = resolution;
                tagRECT exportRect = new tagRECT
                {
                    left = 0,
                    top = 0,
                    right = Convert.ToInt32((double)(activeView.ExportFrame.right * (resolution / 96.0))),
                    bottom = Convert.ToInt32((double)(activeView.ExportFrame.bottom * (resolution / 96.0)))
                };
                IEnvelope pixelBoundsEnv = new EnvelopeClass();
                pixelBoundsEnv.PutCoords((double)exportRect.left, (double)exportRect.bottom, (double)exportRect.right, (double)exportRect.top);
                exporter.PixelBounds = pixelBoundsEnv;
                int hDC = exporter.StartExporting();
                activeView.Output(hDC, Convert.ToInt32(resolution), ref exportRect, null, null);
                exporter.FinishExporting();
                IsExport = true;
            }
            catch
            {
                IsExport = false;
            }
            finally
            {
                exporter.Cleanup();
            }
            return IsExport;
        }

        public static IRgbColor GetRGBColor(int redValue, int greenValue, int blueValue)
        {
            return new RgbColorClass { Red = redValue, Green = greenValue, Blue = blueValue, UseWindowsDithering = true };
        }

        public static List<IFeatureLayer> GetLayers(IMap map, string name)
        {
            List<IFeatureLayer> layers = new List<IFeatureLayer>();
            for (int i = 0; i < map.LayerCount; i++)
            {
                ILayer layer = map.get_Layer(i);
                GetLayerInfo(layer, ref layers, name);
            }

            return layers;
        }

        public static void GetLayerInfo(ILayer Layer, ref List<IFeatureLayer> layers, string name)
        {
            if (Layer as IFeatureLayer != null)
            {
                IFeatureLayer featureLayer = Layer as IFeatureLayer;
                if (name == null)
                {
                    layers.Add(featureLayer);
                }
                else
                {
                    string layerName = featureLayer.Name;
                    if (layerName == name)
                    {
                        layers.Add(featureLayer);
                    }
                }

            }
            else
            {
                if (Layer is IGroupLayer)
                {
                    ICompositeLayer pCompositeLayer = Layer as ICompositeLayer;
                    for (int j = 0; j < pCompositeLayer.Count; j++)
                    {
                        GetLayerInfo(pCompositeLayer.get_Layer(j), ref layers, name);
                    }
                }
            }
        }

        public static List<IFeature> GetSelectFeatures(IMap map)
        {
            List<IFeature> listFeature = new List<IFeature>();
            ISelection selection = map.FeatureSelection;
            IEnumFeatureSetup pEnumFeatureSetup = (IEnumFeatureSetup)selection;
            pEnumFeatureSetup.AllFields = true;
            IEnumFeature pEnumFeature = (IEnumFeature)selection;
            IFeature pFeature = pEnumFeature.Next();
            try
            {
                while (pFeature != null)
                {
                    listFeature.Add(pFeature);
                    pFeature = pEnumFeature.Next();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return listFeature;
        }
    }
}
